<template>
<vs-modal :show.sync="show" effect="fade" width="800px">
  <div class="modal-header" slot="modal-header">
    <h4 class="modal-title">{{$t('common.detail')}}</h4>
  </div>  
  <div class="modal-body" slot="modal-body">
    <form class="form-horizontal fixed-height">
      <div class="form-group" v-for="topoDev in topoDevs" :class="{'has-error': isTopoDevError(topoDev)}">
        <small class="col-sm-3 control-label">{{topoDev.devName}}</small>
        <div class="col-sm-9">
          <div class="input-group">
            <span class="input-group-addon">
              <input type="checkbox" v-model="topoDev.userdef" @change.prevent="onUserDefChange(topoDev)">{{$t('common.userdef')}}
            </span>
            <input type="text" class="form-control" v-model="topoDev.ipaddr" v-show="topoDev.userdef">
            <select class="form-control" v-model="topoDev.devSN" @change.prevent="onBindChange(topoDev)" v-else>
              <option v-for="option in ddisDevs" :value="option.devSN" v-show="isDevOptionShow(topoDev, option)" :disabled="isDevOptionDisabled(topoDev, option)" :class="{'option-disabled': isDevOptionDisabled(topoDev, option)}">{{option.text}}</option>
            </select>
            <span class="input-group-btn">
              <button class="btn btn-default" type="button" @click.prevent="onClearBind(topoDev)" :disabled="topoDev.userdef">{{$t('common.unbind')}}</button>
            </span>
          </div>          
        </div>
      </div>        
    </form>
  </div>
  <div class="modal-footer" slot="modal-footer">
    <button type="button" class="btn btn-default" @click.prevent="onQuit">{{$t('common.quit')}}</button>
    <button type="button" class="btn btn-primary" @click.prevent="onSaveChanges">{{$t('common.savechanges')}}</button>
  </div>    
</vs-modal>  
</template>

<script>
import _ from 'lodash'
import ebus from 'libs/ebus.js'
import toast from 'libs/toast.js'
import msgbox from 'libs/msgbox.js'
import locales from '../locales/ddisDevList.js'
import {printObj, copyObj, isValidIp, hex2Ipaddr, ipaddr2Hex} from 'libs/utils.js'
import * as actions from 'share/server/vuex/actions/devmng.js'
import {devmngApi} from 'share/server/api.js'

export default {
  locales,
  vuex: {
    getters: {
      ddis: (state) => state.devmng.ddis,
      topoSummary: (state) => state.devmng.topoSummary,
      topoBinds: (state) => state.devmng.topoBinds
    },
    actions
  },
  data () {
    return {
      show: false,
      topoDevs: [],
      ddisDevs: []
    }
  },
  methods: {
    onUserDefChange (topoDev) {
      if (!topoDev.userdef) {
        topoDev.devSN = ''
      }
    },
    isTopoDevError (topoDev) {
      if (topoDev.userdef 
        && !isValidIp(topoDev.ipaddr)) {
        return true
      }

      return false
    },
    isDevOptionShow (topoDev, devOption) {
      if (topoDev.devModel.startsWith('audioprocessor')
        && devOption.devModel.startsWith(topoDev.devModel)) {
        return true
      }

      if (topoDev.devModel !== devOption.devModel) {
        return false
      }

      if (devOption.devSN.includes('IPV4')) {
        return false
      }

      return true
    },
    isDevOptionDisabled (topoDev, devOption) {
      if ((devOption.bindTopoId > 0)
        && (devOption.bindTopoId !== topoDev.topoId)) {
        return true
      }

      return false
    },
    onBindChange (topoDev) {
      var devOption = _.find(this.ddisDevs, {bindTopoId: topoDev.topoId})
      if (devOption) {
        if (topoDev.devSN !== devOption.devSN) {
          devOption.bindTopoId = -1
        }
      }

      var devOption = _.find(this.ddisDevs, {devSN: topoDev.devSN})
      if (devOption) {
        if (devOption.bindTopoId !== topoDev.topoId) {
          devOption.bindTopoId = topoDev.topoId
        }
      }
    },
    onClearBind (topoDev) {
      topoDev.devSN = null
      this.onBindChange(topoDev)
    },
    onQuit () {
      this.show = false
    },
    onSaveChanges () {
      var errorCnt = 0
      _.forEach(this.topoDevs, function(item) {
        if (this.isTopoDevError(item)) {
          errorCnt++
        }
      }.bind(this))
      if (errorCnt > 0) {
        toast.w(this, this.$t('common.fail'), this.$t('error.params'))
        return
      }
      let topoDevsOfBind = _.filter(this.topoDevs, (item) => {
        if (item.userdef) {
          if (item.ipaddr === '') {
            return false
          }
        } else {
          if (item.devSN === null || item.devSN === '') {
            return false
          }
        }

        return true
      })
      let topoBinds = _.map(topoDevsOfBind, (item) => {
        var devSN = item.devSN
        if (item.userdef) {
          devSN = ipaddr2Hex(item.ipaddr).toUpperCase() + '-IPV4-0000-0000-000000000000'
        }
        return {
          topoId: item.topoId,
          devSN: devSN,
          devName: item.devName,
          devModel: item.devModel,
          devType: item.devType
        }
      })
      devmngApi.sendCmd('saveTopoBinds', topoBinds).then(function(res) {
        if (res && res.data && res.data.code === 0) {
          toast.s(this, this.$t('common.success'), this.$t('msg.sendCmdSuccess'))
          msgbox.showWait(this.$t('alert.plzWait'), this.$t('common.saving'), 5)
          setTimeout(function() {
            location.reload(true)
          }, 5300)
        } else {
          toast.code(this, res.data)
        }
      }.bind(this))
      this.show = false
    },
    init () {
      let items = _.filter(this.topoSummary.list, (item) => {
        return item.devType !== 'peripheral' && item.devType !== 'addon' && item.devType !== 'server.main' && !item.devType.startsWith('virtual')
      })

      var topoDevs = _.map(items, (item) => {
        var topoDev = {
          topoId: item.topoId,
          devName: item.devName,
          devSN: item.devSN,
          devType: item.devType,
          devModel: item.devModel,
          ipaddr: '',
          userdef: false
        }

        if (topoDev.devSN && topoDev.devSN.includes('IPV4')) {
          topoDev.userdef = true
          topoDev.ipaddr = hex2Ipaddr(topoDev.devSN)
        }

        return topoDev
      })

      this.topoDevs = topoDevs 

      let binds = this.topoBinds.list
      var ddisDevs = _.map(this.ddis.list, (item) => {
        var ddisDev = {
          devSN: item.devSN,
          devModel: item.devModel,
          bindTopoId: -1,
          text: `${item.ipaddr}_${item.devSN}`
        }

        let bind = _.find(binds, {devSN: ddisDev.devSN})
        if (bind) {
          ddisDev.bindTopoId = bind.topoId
        }

        return ddisDev
      })

      ddisDevs = _.orderBy(ddisDevs, ['text'], ['asc'])

      _.forEach(binds, (item) => {
        let ddisDev = _.find(ddisDevs, {devSN: item.devSN})
        let topoDev = _.find(topoDevs, {topoId: item.topoId})
        if ((!ddisDev) && (topoDev)) {
          ddisDevs.push({
            devSN: item.devSN,
            devModel: topoDev.devModel,
            bindTopoId: item.topoId,
            text: `topo[${item.topoId}]_${item.devSN}`         
          })
        }
      })

      this.ddisDevs = ddisDevs           
    },
    onShow (val) {
      this.init()
      this.show = true
    }
  },
  ready () {
    ebus.on('show-topo-binds-detail', this.onShow)
  }
}
</script>

<style scoped>
.option-disabled {
  background-color: #B8B8B8;
}
</style>